﻿#include "core/world.h"
#include "klbmem/klb_mem.h"
#include "core/scene.h"
#include "element/elements.h"
#include "element_ui/elements_ui.h"
#include <assert.h>


/// @brief 初始化创建表
static void world_creater_map_init(world_t* p_world);


/// @brief 创建game世界
world_t* world_create()
{
    world_t* p_world = KLB_MALLOCZ(world_t, 1, 0);

    klb_map_init(&p_world->creater_map);
    p_world->p_scene_hlist = klb_hlist_create(0);

    // 初始化创建表
    world_creater_map_init(p_world);

    return p_world;
}

static int cb_world_clear_scene(void* p_obj, void* p_data)
{
    world_t* p_world = (world_t*)p_obj;
    geobj_t* p_scene = (geobj_t*)p_data;

    //

    return 0;
}

/// @brief 销毁game世界
void world_destroy(world_t* p_world)
{
    // 释放场景
    klb_hlist_clear(p_world->p_scene_hlist, cb_world_clear_scene, p_world);

    klb_map_quit(&p_world->creater_map);

    KLB_FREE(p_world)
}

static geobj_t* world_create_geobj(world_t* p_world, const char* p_type)
{
    geobj_create_cb cb_create = (geobj_create_cb)klb_map_to_ptr(&p_world->creater_map, p_type, NULL);
    if (NULL != cb_create)
    {
        geobj_t* p_node = cb_create();

        return p_node;
    }

    return NULL;
}

/// @brief 添加
int world_append(world_t* p_world, const char* p_type, const char* p_scene, const char* p_path)
{
    if (NULL == p_path)
    {
        if (NULL != klb_hlist_find_iter(p_world->p_scene_hlist, p_scene, strlen(p_scene)))
        {
            return 2;
        }

        geobj_t* p_top = scene_create();

        klb_hlist_push_tail(p_world->p_scene_hlist, p_scene, strlen(p_scene), p_top);
    }
    else
    {
        geobj_t* p_top = (geobj_t*)klb_hlist_find(p_world->p_scene_hlist, p_scene, strlen(p_scene));
        if (NULL == p_top)
        {
            return 1;
        }

        geobj_t* p_obj = world_create_geobj(p_world, p_type);
        if (0 != scene_append(p_top, p_path, p_obj))
        {
            //
            return 2;
        }
    }

    return 0;
}

/// @brief 移除
int world_remove(world_t* p_world, const char* p_scene, const char* p_path)
{
    return 0;
}


//////////////////////////////////////////////////////////////////////////

#define GE2D_CREATEER(KEY_, CREATE_)    { klb_map_set_ptr(&p_world->creater_map, (KEY_), (CREATE_), p_world); }

void world_creater_map_init(world_t* p_world)
{
    // scene
    //GE2D_CREATEER(GE2D_scene, scene_create);

    // element
    GE2D_CREATEER(GE2D_sprite, sprite_create);

    // element ui
    GE2D_CREATEER(GE2D_button, button_create);
}
